/**  
 * @Title CustomExceptionResolver.java
 * @date 2016年3月17日 下午3:37:05
 * @Copyright (c) 2016, unibroad.com Inc. All rights reserved.
 */
package com.strugglerz.web.base;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.strugglerz.model.common.CommonConstants;

/**
 * @Description 自定义统一的异常处理
 * @Class com.unibroad.touchus.web.base.CustomExceptionResolver
 * @author suan@unibroad.com
 * @version V1.0
 */
public class CustomExceptionResolver extends SimpleMappingExceptionResolver {

    private static Logger LOG = LoggerFactory.getLogger(CustomExceptionResolver.class);

    // dispatchservet detectAllHandlerExceptionResolvers 默认为true,

    // {org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver@1011177b,
    // org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0=org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver@521c947a,
    // org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0=org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver@5257ffb3,
    // exceptionResolver=com.unibroad.touchus.web.admin.base.CustomExceptionResolver@f546b01}

    @Override
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
            Object handler, Exception ex) {

        LOG.error("request " + request.getRequestURI() + " exception", ex);
        String viewName = null;
        String errorTipMsg = "操作失败,未知异常!";

        try {

            viewName = determineViewName(ex, request);

            if (ex instanceof UnauthorizedException) {
                errorTipMsg = "操作失败,无相关权限,请核实!";
            } 

            Integer statusCode = determineStatusCode(request, viewName);
            if (statusCode == null || statusCode < 400) {
                statusCode = 500;
            }
            applyStatusCodeIfPossible(request, response, statusCode);

            // 异步请求
            if (StringUtils.contains(request.getHeader("accept"), "application/json")
                    || StringUtils.contains(request.getHeader("X-Requested-With"), "XMLHttpRequest")) {
                ModelMap modelMap = new ModelMap();
                modelMap.put(CommonConstants.OPERATE_RESULT_KEY_SUCESS, false);
                modelMap.put(CommonConstants.OPERATE_RESULT_KEY_MSG, errorTipMsg);
                return new ModelAndView(new FastJsonJsonView(), modelMap);
            }

        } catch (Exception e) {
            LOG.error("操作失败,异常输出处理异常", e);
        }

        viewName = StringUtils.isBlank(viewName) ? "error/500" : viewName;

        return getModelAndView(viewName, errorTipMsg, ex);
    }

    private ModelAndView getModelAndView(String viewName, String exMsg, Exception ex) {
        ModelAndView mv = new ModelAndView(viewName);
        mv.addObject(CommonConstants.ERROR_PAGE_TAG, true);
        mv.addObject(CommonConstants.ERROR_MSG_TIP_KEY, exMsg);
        mv.addObject(DEFAULT_EXCEPTION_ATTRIBUTE, ex.getStackTrace());
        return mv;
    }
}
